package com.javaex.book.web;

import java.io.IOException;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.javaex.book.utils.Constants.Response;
import com.javaex.book.utils.JsonUtils;
import com.javaex.book.utils.Pages;

/**
 * 拦截所有请求，并进行分发
 * 接收Controller的处理结果，并响应客户端
 */
@WebServlet("/")
public class DispatcherServlet extends HttpServlet {
	
	private static final long serialVersionUID = 1L;
	private static final Logger logger = LoggerFactory.getLogger(DispatcherServlet.class);
	private HandlerMapping handlerMapping;

	@Override
	public void init(ServletConfig config) throws ServletException {
		super.init(config);
		handlerMapping = new HandlerMapping();
	}

	@Override
	protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// 去除uri中的ContextPath，用于匹配Handler
		String uri = req.getRequestURI();
		if (!req.getContextPath().isEmpty()) {
			uri = uri.substring(req.getContextPath().length());
		}
		
		// 获取Handler
		Handler handler = handlerMapping.getHandler(uri, req.getMethod());
		// 如果没有匹配的Handler，则返回404页面
		if (handler == null) {
			responseClient(req, resp, Pages.NOT_FOUND);
			return;
		} 
		
		// 执行业务方法，处理请求
		Object result = null;
		try {
			result = handler.execute(req, resp);
		} catch (Exception e) {
			// 前往 500 错误页面
			result = Pages.SERVET_ERROR;
			throw e;
		}
		
		// 响应客户端
		responseClient(req, resp, result);
	}

	/**
	 * 响应客户端
	 * @param req 
	 * @param resp 
	 * @param result 响应数据
	 */
	private void responseClient(HttpServletRequest req, HttpServletResponse resp, Object result) {
		if (result == null) {
			return;
		}
		try {
			// 判断响应类型。如果是字符串类型，则响应页面。如果是Object类型，则响应json数据
			if (!(result instanceof String)) {
				resp.setContentType("application/json;charset=utf-8");
				String json = JsonUtils.stringify(result);
				resp.getWriter().append(json);
				return;
			} 
			
			// 判断是转发、重定向还是直接跳转到某个页面
			String[] resArr = result.toString().trim().split(" ");
			if (resArr.length == 1) {
				req.getRequestDispatcher(resArr[0]).forward(req, resp);
				return;
			}
			
			if (Response.REDIRECT.equalsIgnoreCase(resArr[0])) {	// 重定向
				resp.sendRedirect(req.getContextPath() + resArr[1]);
			} else if (Response.FORWARD.equalsIgnoreCase(resArr[0])) { // 转发
				req.getRequestDispatcher(resArr[1]).forward(req, resp);
			} 
		} catch (Exception e) {
			logger.error("服务器响应客户端失败", e);
		}
	}
}
